﻿using Amazon.Runtime.Internal;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Nasty.Core.Config;
using Nasty.Core.Entity.System;
using Nasty.Core.LoadParams;
using Nasty.Core.Registry;
using Nasty.Core.Security;
using Nasty.Core.Session;
using Nasty.Core.SuperExtension;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.Json;
using System.Text.Json.Nodes;
using System.Text.Json.Serialization;
using static System.Runtime.InteropServices.JavaScript.JSType;

namespace Nasty.Core.Attributes
{
    public class NastyActionLog : ActionFilterAttribute
    {

        /// <summary>
        /// 请求体第三方标记
        /// 单体标记例如：Id(Id当标记)/User.Id(用户对象中Id当标记)
        /// 联合标记例如：Id,Code (使用Id和Code进行联合标记，程序会进行合并成一个字符串)
        /// </summary>
        public string RequestThirdId { get; set; } = string.Empty;

        /// <summary>
        /// 响应体第三方标记
        /// 单体标记例如：Id(Id当标记)/User.Id(用户对象中Id当标记)
        /// 联合标记例如：Id,Code (使用Id和Code进行联合标记，程序会进行合并成一个字符串)
        /// </summary>
        public string ResponseThirdId { get; set; } = string.Empty;



        // 可以通过构造函数注入服务
        public NastyActionLog()
        {

        }

        public override void OnActionExecuting(ActionExecutingContext context)
        {

        }

        public override void OnActionExecuted(ActionExecutedContext context)
        {
            if (context.Exception != null)
            {
                base.OnActionExecuted(context);
                return;
            }

            try
            {
                var descriptor = ((Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor)context.ActionDescriptor);

                context.HttpContext.Request.Body.Position = 0;
                using (var reader = new StreamReader(context.HttpContext.Request.Body,
                    Encoding.UTF8,
                    detectEncodingFromByteOrderMarks: true,
                    bufferSize: 1024,
                    leaveOpen: true))
                {
                    dynamic result = (context.Result as ObjectResult)?.Value;

                    string requestBody = reader.ReadToEndAsync().Result;
                    string responseBody = JsonConvert.SerializeObject(result);

                    var log = CreateActionLog(descriptor, this.RequestThirdId, this.ResponseThirdId, requestBody, responseBody);
                    var db = AppSession.CurrentDb.Value;
                    db.Add(log);

                }
            }
            catch (Exception ex)
            {
                var error = ex;
            }


            base.OnActionExecuted(context);
        }


        public static ActionLog CreateActionLog(Microsoft.AspNetCore.Mvc.Controllers.ControllerActionDescriptor descriptor,
           string requestThirdId, string responseThirdId, string requestBody, string responseBody)
        {

            var displayName = descriptor.DisplayName;
            var controllerName = descriptor.ControllerName;
            var actionName = descriptor.ActionName;

            var log = new ActionLog()
            {
                DisplayName = displayName,
                ControllerName = controllerName,
                ActionName = actionName,
                RequestContent = requestBody,
                ResponseContent = responseBody,
                DestroyDay = 90
            };

            if (!string.IsNullOrEmpty(requestThirdId))
            {
                try
                {
                    var requestConfig = requestBody.BuildConfigurationFromJson();
                    var items = requestThirdId.Split(',');
                    var list = new List<string>();

                    foreach (var item in items)
                    {
                        var itemValue = requestConfig.GetValue<string>(item);
                        list.Add(itemValue);
                    }

                    var thirdId = string.Join("-", list);

                    log.RequestThirdId = thirdId;
                }
                catch (Exception ex)
                {
                    var error = ex;
                }
            }


            if (!string.IsNullOrEmpty(responseThirdId))
            {
                try
                {
                    var responseConfig = responseBody.BuildConfigurationFromJson();
                    var items = responseThirdId.Split(',');
                    var list = new List<string>();

                    foreach (var item in items)
                    {
                        var itemValue = responseConfig.GetValue<string>(item);
                        list.Add(itemValue);
                    }

                    var thirdId = string.Join("-", list);
                    log.ResponseThirdId = thirdId;
                }
                catch (Exception ex)
                {
                    var error = ex;
                }
            }


            return log;
        }

    }
}
